from fastapi import HTTPException, APIRouter, Depends, Request
from models.address import Address
from models.user import User
from schemas.address import AddressCreate, AddressOut
from tortoise.exceptions import DoesNotExist, MultipleObjectsReturned
from typing import List
from pydantic import BaseModel
from fastapi.security import OAuth2PasswordBearer
# 替换为实际的 Token 验证工具（需确保 verify_token 逻辑正确）
from utils.generate_verfy_token import verify_token  
from utils.generate_verfy_token import verify_token
from typing import Optional
import logging

router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
logger = logging.getLogger(__name__)

class StatusResponse(BaseModel):
    message: str

# 【关键修复】确保 Token 验证逻辑正确，返回 payload 或用户信息
async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = await verify_token(token, return_payload=True)  
        username = payload.get("sub")
        if not username:
            raise HTTPException(status_code=401, detail="Token 无效：缺少用户标识")
        
        # 从数据库查询用户（确保 User 模型存在且字段正确）
        user = await User.get_or_none(username=username)
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        return user

    except HTTPException as e:
        raise  # 直接抛出已定义的 HTTP 异常
    except Exception as e:
        logger.error(f"用户认证失败: {str(e)}")
        raise HTTPException(status_code=401, detail="凭证验证失败")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        # 验证 Token 并提取 payload
        payload = await verify_token(token, return_payload=True)
        username = payload.get("sub")
        if not username:
            raise HTTPException(status_code=401, detail="Token 无效：缺少用户标识")

        # 从数据库查询用户
        user = await User.get_or_none(username=username)
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
            
        return user

    except HTTPException as e:
        raise  # 直接传递已有的 HTTP 异常
    except Exception as e:
        logger.error(f"用户认证失败: {str(e)}")
        raise HTTPException(status_code=401, detail="凭证验证失败")
    

@router.post("/address", response_model=AddressOut)
async def create_address(
    address: AddressCreate, 
    user: User = Depends(get_current_user)
):
    try:
        # 创建地址并关联用户
        # 创建新地址，关联到当前认证用户
        address_obj = await Address.create(
            user=user,
            name=address.name,
            phone=address.phone,
            address=address.address,
            is_default=address.is_default
        )
        
        # 设为默认地址时，取消其他地址默认状态
        if address.is_default:
            await Address.filter(
                user=user, is_default=True
            ).exclude(id=address_obj.id).update(is_default=False)
            
        # 返回标准格式（与前端 AddressOut 严格匹配）
        # 直接返回AddressOut模型
        return AddressOut(
            id=address_obj.id,
            user_id=user.id,
            name=address_obj.name,
            phone=address_obj.phone,
            address=address_obj.address,
            is_default=address_obj.is_default
        )

    except MultipleObjectsReturned:
        logger.error("系统异常：手机号重复")
        raise HTTPException(status_code=500, detail="系统异常：手机号冲突")
    except Exception as e:
        logger.error(f"创建地址失败: {str(e)}")
        raise HTTPException(status_code=500, detail="创建地址失败，请重试")

        raise HTTPException(status_code=500, detail="系统异常")
    except Exception as e:
        logger.error(f"创建地址失败: {str(e)}")
        raise HTTPException(status_code=500, detail="创建地址失败")

@router.get("/getaddress", response_model=List[AddressOut])
async def get_address(user: User = Depends(get_current_user)):
    try:
        # 查询当前用户的所有地址
        addresses = await Address.filter(user=user).all()
        
        # 确保返回数据与前端 AddressOut 完全匹配
        return [
            AddressOut(
                id=addr.id,
                user_id=user.id,
                name=addr.name,
                phone=addr.phone,
                address=addr.address,  # 后端存储完整地址（省市区+详细地址）
                is_default=addr.is_default
            ) 
            for addr in addresses
        ]

    except Exception as e:
        logger.error(f"获取地址列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取地址失败，请重试")

        addresses = await Address.filter(user=user).all()
        
        return [AddressOut(
            id=address.id,
            user_id=user.id,
            name=address.name,
            phone=address.phone,
            address=address.address,
            is_default=address.is_default
        ) for address in addresses]
        
    except Exception as e:
        logger.error(f"获取地址列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取地址列表失败")
    

@router.post("/address/{address_id}", response_model=StatusResponse)
async def update_address(
    address_id: int,
    address_data: AddressCreate,
    user: User = Depends(get_current_user)
):
    try:
        # 检查地址归属（必须属于当前用户）
        address = await Address.get(id=address_id, user=user)
        
        # 部分更新地址字段
        await address.update_from_dict(address_data.dict(exclude_unset=True))
        await address.save()
        
        # 设为默认地址时，取消其他地址默认状态
        if address_data.is_default:
            await Address.filter(
                user=user, is_default=True
            ).exclude(id=address_id).update(is_default=False)
            
        return StatusResponse(message="地址更新成功")

    except DoesNotExist:
        raise HTTPException(status_code=404, detail="地址不存在或无权限")
    except Exception as e:
        raise HTTPException(status_code=500, detail="更新地址失败，请重试")
        # 检查地址是否存在且属于当前用户
        address = await Address.get(id=address_id, user=user)
        
        # 更新地址信息
        await address.update_from_dict(address_data.dict(exclude_unset=True))
        await address.save()
        
        # 如果设为默认地址，取消其他地址的默认状态
        if address_data.is_default:
            await Address.filter(user=user, is_default=True).exclude(id=address_id).update(is_default=False)
            
        return StatusResponse(message="地址更新成功")
        
    except DoesNotExist:
        raise HTTPException(status_code=404, detail="地址不存在")
    except Exception as e:
        raise HTTPException(status_code=500, detail="更新地址失败")
